package com.jt.www.biz.order_pc.service.impl;

import com.jt.www.enums.endorse.GradeEnum;
import com.jt.www.enums.endorse.PdTypeEnum;
import com.jt.www.model.reps.GenericListResponse;
import com.jt.www.model.vo.endorse.CheckNumVO;
import com.jt.www.model.vo.endorse.EduInsuredInfo;
import com.jt.www.model.vo.endorse.EduInsuredObject;
import com.jt.www.model.vo.endorse.EduQueryEndorsementTypeAndCountInfo;
import com.jt.www.model.woxuebao.toubao.ContextExtend;
import com.jt.www.remote.PolClient;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 计算实责批单需要付费人数
 *
 * @author admin_ltf
 * @create 2019-06-25 10:23
 */
@Service
public class EndorseCheckXZNumService {

    public static final Logger log = LoggerFactory.getLogger(EndorseCheckXZNumService.class);
    @Autowired
    private PolClient polClient;

    @Value("${jtpf.benefit-rate}")
    private String benefitRate;

    // todo  计算实责：实责有两个附加险：实习无过失，附加被保险人。
    // 和前端沟通，需要返回  按照险种人数的汇总。举例：双附加险 1人，只买附加险A的1人。返回 双附加险1人  附加险A2人。
    public List<CheckNumVO> checkQGSZNum(List<CheckNumVO> paramList) throws Exception {
        Integer originalNum = paramList.get(0).getOriginalNum();
        Integer currentNum = paramList.get(0).getCurrentNum();
        String type = PdTypeEnum.getValueByPdType(paramList.get(0).getType());
        String policyNo = paramList.get(0).getPolicyNo();
        if ("no".equals(type)) {
            return paramList;
        }
        // 目前先不用循环 list  循环的目的是 获取到每个年级的数量 做扣减。应该先去调用远程接口 ，
        // 计算历史批单记录。
        // 调用批单中心接口，查询批单记录
        //历史参与批单总人数
        Integer totalNum = 0;
        // 首先调用批单中心接口  查询批单记录信息
        ResponseEntity<GenericListResponse<EduQueryEndorsementTypeAndCountInfo>> genericListResponseResponseEntity = polClient.queryEduEndorsemenstInfo(policyNo);
        if (genericListResponseResponseEntity != null) {
            GenericListResponse<EduQueryEndorsementTypeAndCountInfo> body = genericListResponseResponseEntity.getBody();
            String code = body.getCode();
            String valueByPdType = "";
            if ("0000".equals(code)) {
                // 如果本次是批加。那么从记录中只取批加的记录。
                List<EduQueryEndorsementTypeAndCountInfo> list = body.getList();
                if (list != null && list.size() > 0) {
                    for (EduQueryEndorsementTypeAndCountInfo vo : list) {
                        // 先判断类型  然后这一个对象中 所有的数据都是这一个类型  ok   todo
                        String endorsementsType = vo.getEndorsementsType();
                        if ("01".equals(endorsementsType) ||
                                "04".equals(endorsementsType) ||
                                "10".equals(endorsementsType) ||
                                "11".equals(endorsementsType) ||
                                "12".equals(endorsementsType) ||
                                "13".equals(endorsementsType) ||
                                "14".equals(endorsementsType)) {
                            continue;
                        }
                        //批改类型转换
                        valueByPdType = PdTypeEnum.getValueByPdType(endorsementsType);
                        if (type.equals(valueByPdType)) {
                            // S_O_000019 学生年级 one two three four five 就这5个年级
                            List<EduInsuredInfo> insuredList = vo.getInsuredList();
                            if (insuredList != null && insuredList.size() > 0) {
                                for (EduInsuredInfo eduInsuredInfo : insuredList) {
                                    Integer insuranceObjectCount = eduInsuredInfo.getInsuranceObjectCount();
                                    List<EduInsuredObject> insuranceObjects = eduInsuredInfo.getInsuranceObjects();
                                    if (insuranceObjects != null && insuranceObjects.size() > 0) {
                                        for (EduInsuredObject eduInsuredObject : insuranceObjects) {
                                            List<ContextExtend> extendList = eduInsuredObject.getExtendList();
                                            if (extendList != null && extendList.size() > 0) {
                                                for (ContextExtend contextExtend : extendList) {
                                                    String key = contextExtend.getKey();

                                                    if ("S_O_100004".equals(key)) {
                                                        String value = contextExtend.getValue();
                                                        if (StringUtils.isEmpty(value)) {
                                                            value = "0";
                                                        }
                                                        Integer num = Integer.valueOf(value);
                                                        if ("03".equals(endorsementsType)) {
                                                            totalNum += num;
                                                        } else if ("02".equals(endorsementsType)) {
                                                            // ("sub".equals(valueByPdType))
                                                            totalNum += num;
                                                        } else if ("05".equals(endorsementsType)) {
                                                            log.info("有过协议批加的记录，原保单人数增加");
                                                            originalNum += num;
                                                        } else if ("06".equals(endorsementsType)) {
                                                            log.info("有过协议批减的记录，原保单人数减少");
                                                            originalNum -= num;
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }


                    }
                }
            } else {
                throw new Exception("调用批单中心查询批单记录失败");
            }
        }
        // 第二步：原始人数乘以优惠率  计算应该优惠的人数 num
        Double rate = Double.valueOf(benefitRate);
        // 四舍五入
        Long round = Math.round(originalNum * rate);
        //这张保单应该优惠的总人数
        int num = round.intValue();

        // 本次可以优惠人数
        int subNum = num - totalNum;

        List<CheckNumVO> resultList = new ArrayList<>();
        // 需要分 增加 还是 减少
        if ("add".equals(type)) {
            if (subNum > 0) {
                // 计算 当前批单人数  和  优惠名额的差值
                int i = currentNum - subNum;
                if (i > 0) {
                    // 当前批单人数 多 ，需要做扣减
                    // todo  计算实责：实责有两个附加险：实习无过失，附加被保险人。 获取到传参中的数据 先扣除有两个附加险的，再扣除实习无过失，附加被保险人，从高年级先扣。
                    // 遍历入参 先把每个人数 都拿掉
                    resultList = paramList;
                    // 首先把实责的两个附加险的人数 按照年级 组装一个map
                    Map<String, Integer> map = new HashMap<>();
                    for (CheckNumVO checkNumVO : paramList) {
                        String grade = checkNumVO.getGrade();
                        Integer insNum3 = checkNumVO.getInsNum3();
                        map.put(grade, insNum3);
                    }
                    byte grade = 7;
                    String gradeCode = GradeEnum.getEnCodeByCode(grade);
                    // 最高年级的附加险数量
                    Integer highGradeNum = map.get(gradeCode);
                    if (highGradeNum == null) {
                        highGradeNum = 0;
                    }

                    // 用递归 做扣减
                    resultList = calculateTwoNum(resultList, subNum, grade, highGradeNum, map);

                } else {
                    // 当前批单人数少   ， 不需要扣减人数 全部免费
                    resultList = paramList;
                    for (CheckNumVO checkNumVO : resultList) {
                        checkNumVO.setSxAInsMfNum(checkNumVO.getInsNum3());
                        checkNumVO.setSxAInsFfNum(0);

                        checkNumVO.setInsMfNum(checkNumVO.getInsNum2() + checkNumVO.getInsNum3());
                        checkNumVO.setInsFfNum(0);
                        checkNumVO.setInsSxMfNum(checkNumVO.getInsNum1() + checkNumVO.getInsNum3());
                        checkNumVO.setInsSxFfNum(0);

                        checkNumVO.setInsNum5(checkNumVO.getGradeNum());
                        checkNumVO.setInsNum6(0);
                    }
                }

            } else {
                // 当前优惠人数 用完，全部需要付费
                resultList = paramList;

                for (CheckNumVO checkNumVO : resultList) {
                    checkNumVO.setSxAInsMfNum(0);
                    checkNumVO.setSxAInsFfNum(checkNumVO.getInsNum3());

                    checkNumVO.setInsMfNum(0);
                    checkNumVO.setInsFfNum(checkNumVO.getInsNum2() + checkNumVO.getInsNum3());

                    checkNumVO.setInsSxMfNum(0);
                    checkNumVO.setInsSxFfNum(checkNumVO.getInsNum1() + checkNumVO.getInsNum3());
                    checkNumVO.setInsNum5(0);
                    checkNumVO.setInsNum6(checkNumVO.getGradeNum());
                }
            }

        } else if ("sub".equals(type)) {

            // 扣减 优惠名额：subNum
            if (subNum > 0) {
                // 计算 当前批单人数  和  优惠名额的差值
                int i = currentNum - subNum;
                if (i >= 0) {
                    // 和批加的逻辑相反需要注意
                    // 当前批单人数 多 ，需要做扣减，
                    // todo 获取到传参中的数据 先扣除只买主险的，再扣除买附加被保险人的，再扣除实习无过失的，最后扣除双保险的，从低年级先扣。
                    resultList = paramList;
                    // 把实责的主险  按照年级 组装一个map
                    Map<String, Integer> map = new HashMap<>();
                    for (CheckNumVO checkNumVO : paramList) {
                        String grade = checkNumVO.getGrade();
                        Integer xzNum4 = checkNumVO.getInsNum4();
                        map.put(grade, xzNum4);
                    }
                    // 做具体扣减 从低年级开始扣
                    byte grade = 1;
                    String gradeCode = GradeEnum.getEnCodeByCode(grade);
                    // 最高年级的附加险数量
                    Integer highGradeNum = map.get(gradeCode);
                    if (highGradeNum == null) {
                        highGradeNum = 0;
                    }

                    // 用递归 做扣减
//                        resultList = calculateSubNum(resultList,subNum,grade,highGradeNum,map);
                    resultList = calculateSubZxNum(resultList, subNum, grade, highGradeNum, map);


                } else {
                    // 当前批单人数少   ， 不需要扣减人数 全部免费 ，不需要退款
                    resultList = paramList;
                    for (CheckNumVO checkNumVO : resultList) {
                        checkNumVO.setSxAInsMfNum(checkNumVO.getInsNum3());
                        checkNumVO.setSxAInsFfNum(0);
                        checkNumVO.setInsMfNum(checkNumVO.getInsNum2() + checkNumVO.getInsNum3());
                        checkNumVO.setInsFfNum(0);
                        checkNumVO.setInsSxMfNum(checkNumVO.getInsNum1() + checkNumVO.getInsNum3());
                        checkNumVO.setInsSxFfNum(0);

                        checkNumVO.setInsNum5(checkNumVO.getGradeNum());
                        checkNumVO.setInsNum6(0);
                    }
                }

            } else {

                // 当前优惠人数 用完，全部需要退款
                resultList = paramList;

                for (CheckNumVO checkNumVO : resultList) {
                    checkNumVO.setSxAInsMfNum(0);
                    checkNumVO.setSxAInsFfNum(checkNumVO.getInsNum3());
                    checkNumVO.setInsNum5(0);
                    checkNumVO.setInsNum6(checkNumVO.getGradeNum());
                    checkNumVO.setInsMfNum(0);
                    checkNumVO.setInsFfNum(checkNumVO.getInsNum2() + checkNumVO.getInsNum3());
                    checkNumVO.setInsSxMfNum(0);
                    checkNumVO.setInsSxFfNum(checkNumVO.getInsNum1() + checkNumVO.getInsNum3());

                }
            }

        }
        return resultList;
    }


    /**
     * 实责 双附加险人数处理
     *
     * @param resultList   结果集
     * @param subNum       优惠名额
     * @param grade        年级
     * @param highGradeNum 最高年级的附加险数量
     * @param map          年级 和年级附加险数量  map
     * @return
     */
    private List<CheckNumVO> calculateTwoNum(List<CheckNumVO> resultList, int subNum, byte grade, Integer highGradeNum, Map<String, Integer> map) {

        // todo  计算实责：实责有两个附加险：实习无过失，附加被保险人。
        // 获取到传参中的数据 先扣除有两个附加险的，再扣除实习无过失，附加被保险人，从高年级先扣。
        // 该方法  是  计算 两个附加险的

        if (highGradeNum != null && highGradeNum > 0) {
            int i = subNum - highGradeNum;
            // 该年级双附加险批改人数不足优惠人数
            if (i > 0) {// 去找下一年级
                //剩余优惠人数
                for (CheckNumVO checkNumVO : resultList) {
                    if (StringUtils.equals(GradeEnum.getEnCodeByCode(grade), checkNumVO.getGrade())) {
                        if (checkNumVO.getSxAInsMfNum() != null && checkNumVO.getSxAInsMfNum().compareTo(0) > 0) {
                            checkNumVO.setSxAInsMfNum(checkNumVO.getSxAInsMfNum() + highGradeNum);
                        } else {
                            checkNumVO.setSxAInsMfNum(highGradeNum);
                        }

                    }
                }
                subNum = subNum - highGradeNum;
                //下一个年级
                grade -= 1;
                String gradeCode = GradeEnum.getEnCodeByCode(grade);
                // 下一个年级双附加险人数
                highGradeNum = map.get(gradeCode);
                if (grade > 0) {
                    calculateTwoNum(resultList, subNum, grade, highGradeNum, map);
                }
                if (grade < 1 && subNum > 0) {
                    // 说明 扣完双附加险 的人数后 ，优惠名额还有剩余，需要继续递归循环，去循环 实习无过失的人数，也是从高年级向低年级依次扣
                    // 首先组装一个  年级  主实习无过失人数的map
                    Map<String, Integer> zxMap = new HashMap<>();
                    for (CheckNumVO checkNumVO : resultList) {
                        String nj = checkNumVO.getGrade();
                        //附加实习无过失附加险人数
                        Integer insNum1 = checkNumVO.getInsNum1();
                        zxMap.put(nj, insNum1);
                    }
                    grade = 7;
                    gradeCode = GradeEnum.getEnCodeByCode(grade);
                    // 最高年级的只买 实习无过失 的人数
                    highGradeNum = zxMap.get(gradeCode);
                    if (highGradeNum == null) {
                        highGradeNum = 0;
                    }
                    resultList = calculateSxWgsNum(resultList, subNum, grade, highGradeNum, zxMap);
                }
            } else {
                // 直接在本年级扣了
                for (CheckNumVO checkNumVO : resultList) {
                    String grade1 = checkNumVO.getGrade();
                    String currentGrade = GradeEnum.getEnCodeByCode(grade);
                    // 根据one 得到 1
                    byte codeByenCode = GradeEnum.getCodeByenCode(grade1);
                    if (StringUtils.equals(currentGrade, grade1)) {// 当前年级 双附加险有免费的，也有付费的   其他都是付费 ，由于是汇总，所以需要计算下

                        checkNumVO.setSxAInsMfNum(subNum);
                        checkNumVO.setSxAInsFfNum(checkNumVO.getInsNum3() - subNum);

                        checkNumVO.setInsMfNum(subNum);
                        checkNumVO.setInsFfNum(checkNumVO.getInsNum2() + checkNumVO.getInsNum3() - subNum);
                        checkNumVO.setInsSxMfNum(subNum);
                        checkNumVO.setInsSxFfNum(checkNumVO.getInsNum1() + checkNumVO.getInsNum3() - subNum);

                        checkNumVO.setInsNum5(subNum);
                        checkNumVO.setInsNum6(checkNumVO.getGradeNum() - subNum);
                    } else if (codeByenCode < grade) {// 比当前年级小的  还没扣到 双附加险是付费  其他也是付费
                        checkNumVO.setSxAInsMfNum(0);
                        checkNumVO.setSxAInsFfNum(checkNumVO.getInsNum3());

                        checkNumVO.setInsMfNum(0);
                        checkNumVO.setInsFfNum(checkNumVO.getInsNum2() + checkNumVO.getInsNum3());
                        checkNumVO.setInsSxMfNum(0);
                        checkNumVO.setInsSxFfNum(checkNumVO.getInsNum1() + checkNumVO.getInsNum3());

                        checkNumVO.setInsNum5(0);
                        checkNumVO.setInsNum6(checkNumVO.getGradeNum());
                    } else if (codeByenCode > grade) {// 比当前年级大的  已经扣完 双附加险全部免费  其他都是付费
                        checkNumVO.setSxAInsMfNum(checkNumVO.getInsNum3());
                        checkNumVO.setSxAInsFfNum(0);

                        checkNumVO.setInsMfNum(checkNumVO.getInsNum3());
                        checkNumVO.setInsFfNum(checkNumVO.getInsNum2());
                        checkNumVO.setInsSxMfNum(checkNumVO.getInsNum3());
                        checkNumVO.setInsSxFfNum(checkNumVO.getInsNum1());

                        checkNumVO.setInsNum5(checkNumVO.getInsNum3());
                        checkNumVO.setInsNum6(checkNumVO.getGradeNum() - checkNumVO.getInsNum3());
                    }

                }
            }

        } else {
            // 去找下一年级
            grade -= 1;
            String gradeCode = GradeEnum.getEnCodeByCode(grade);
            // 最高年级的两个附加险的人数
            highGradeNum = map.get(gradeCode);
            if (highGradeNum == null) {
                highGradeNum = 0;
            }
            if (grade > 0) {
                calculateTwoNum(resultList, subNum, grade, highGradeNum, map);
            }

        }


        return resultList;
    }

    /**
     * 附加实习无过失人数
     *
     * @param resultList
     * @param subNum
     * @param grade
     * @param highGradeNum
     * @param zxMap
     * @return
     */
    private List<CheckNumVO> calculateSxWgsNum(List<CheckNumVO> resultList, int subNum, byte grade, Integer highGradeNum, Map<String, Integer> zxMap) {

        if (highGradeNum != null && highGradeNum > 0) {
            // 优惠名额 - 高年级实习无过失险人数
            int i = subNum - highGradeNum;
            if (i > 0) {
                for (CheckNumVO checkNumVO : resultList) {
                    if (StringUtils.equals(GradeEnum.getEnCodeByCode(grade), checkNumVO.getGrade())) {
                        if (checkNumVO.getInsSxMfNum() != null && checkNumVO.getInsSxMfNum().compareTo(0) > 0) {
                            checkNumVO.setInsSxMfNum(checkNumVO.getInsSxMfNum() + highGradeNum);
                        } else {
                            checkNumVO.setInsSxMfNum(highGradeNum);
                        }

                    }
                }
                // 去找下一个年级
                subNum = subNum - highGradeNum;
                grade -= 1;
                String gradeCode = GradeEnum.getEnCodeByCode(grade);
                // 最高年级的附加险数量
                highGradeNum = zxMap.get(gradeCode);
                if (highGradeNum == null) {
                    highGradeNum = 0;
                }
                if (grade > 0) {
                    calculateSxWgsNum(resultList, subNum, grade, highGradeNum, zxMap);
                }

                if (subNum > 0) {
                    // todo  腾飞
                    // 说明 扣完实习无过失的人数后 ，优惠名额还有剩余，需要继续递归循环，去循环 附加被保险人的人数，也是从高年级向低年级依次扣
                    // 首先组装一个  年级  附加被保险人 人数的map
                    Map<String, Integer> fjMap = new HashMap<>();
                    for (CheckNumVO checkNumVO : resultList) {
                        String nj = checkNumVO.getGrade();
                        Integer insNum2 = checkNumVO.getInsNum2();
                        fjMap.put(nj, insNum2);
                    }
                    grade = 7;
                    gradeCode = GradeEnum.getEnCodeByCode(grade);
                    // 最高年级的只买 附加被保险人 的人数
                    highGradeNum = fjMap.get(gradeCode);
                    if (highGradeNum == null) {
                        highGradeNum = 0;
                    }
                    resultList = calculateFjBbxrNum(resultList, subNum, grade, highGradeNum, fjMap);
                }
            } else {
                // 直接在本年级扣了
                for (CheckNumVO checkNumVO : resultList) {
                    String grade1 = checkNumVO.getGrade();
                    String currentGrade = GradeEnum.getEnCodeByCode(grade);

                    // 根据one 得到 1  当前年级
                    byte codeByenCode = GradeEnum.getCodeByenCode(grade1);

                    if (StringUtils.equals(currentGrade, grade1)) {// 本年级 实习无过失险人数 有免费也有付费  双附加险 全部免费  其他 全部付费
                        checkNumVO.setSxAInsMfNum(checkNumVO.getInsNum3());
                        checkNumVO.setSxAInsFfNum(0);
                        // 附加被保险人
                        checkNumVO.setInsMfNum(checkNumVO.getInsNum3());
                        checkNumVO.setInsFfNum(checkNumVO.getInsNum2());
                        // 实习无过失
                        checkNumVO.setInsSxMfNum(subNum + checkNumVO.getInsNum3());
                        checkNumVO.setInsSxFfNum(checkNumVO.getInsNum1() - subNum);

                        checkNumVO.setInsNum5(subNum + checkNumVO.getInsNum3());
                        checkNumVO.setInsNum6(checkNumVO.getGradeNum() - checkNumVO.getInsNum3() - subNum);
                    } else if (codeByenCode > grade) {// 当前年级的高年级：双附加险 全部免费，实习无过失险人数，全部免费； 其他付费

                        checkNumVO.setSxAInsMfNum(checkNumVO.getInsNum3());
                        checkNumVO.setSxAInsFfNum(0);

                        // 附加被保险人
                        checkNumVO.setInsMfNum(checkNumVO.getInsNum3());
                        checkNumVO.setInsFfNum(checkNumVO.getInsNum2());
                        // 实习无过失
                        checkNumVO.setInsSxMfNum(checkNumVO.getInsNum1() + checkNumVO.getInsNum3());
                        checkNumVO.setInsSxFfNum(0);

                        checkNumVO.setInsNum5(checkNumVO.getInsNum1() + checkNumVO.getInsNum3());
                        checkNumVO.setInsNum6(checkNumVO.getGradeNum() - checkNumVO.getInsNum3() - checkNumVO.getInsNum1());
                    } else if (codeByenCode < grade) {// 当前年级的低年级：双附加险 全部免费，其他付费

                        checkNumVO.setSxAInsMfNum(checkNumVO.getInsNum3());
                        checkNumVO.setSxAInsFfNum(0);

                        // 附加被保险人
                        checkNumVO.setInsMfNum(checkNumVO.getInsNum3());
                        checkNumVO.setInsFfNum(checkNumVO.getInsNum2());
                        // 实习无过失
                        checkNumVO.setInsSxMfNum(checkNumVO.getInsNum3());
                        checkNumVO.setInsSxFfNum(checkNumVO.getInsNum1());

                        checkNumVO.setInsNum5(checkNumVO.getInsNum3());
                        checkNumVO.setInsNum6(checkNumVO.getGradeNum() - checkNumVO.getInsNum3());
                    }

                }
            }

        } else {
            // 去找下一个年级
            grade -= 1;
            String gradeCode = GradeEnum.getEnCodeByCode(grade);
            // 最高年级的附加险数量
            highGradeNum = zxMap.get(gradeCode);
            if (highGradeNum == null) {
                highGradeNum = 0;
            }
            if (grade > 0) {
                calculateSxWgsNum(resultList, subNum, grade, highGradeNum, zxMap);
            }

        }

        return resultList;
    }

    private List<CheckNumVO> calculateFjBbxrNum(List<CheckNumVO> resultList, int subNum, byte grade, Integer highGradeNum, Map<String, Integer> zxMap) {

        if (highGradeNum != null && highGradeNum > 0) {
            // 优惠名额 - 高年级附加被保险人 人数
            int i = subNum - highGradeNum;
            if (i > 0) {
                for (CheckNumVO checkNumVO : resultList) {
                    if (StringUtils.equals(GradeEnum.getEnCodeByCode(grade), checkNumVO.getGrade())) {
                        if (checkNumVO.getInsMfNum() != null && checkNumVO.getInsMfNum().compareTo(0) > 0) {
                            checkNumVO.setInsMfNum(checkNumVO.getInsMfNum() + highGradeNum);
                        } else {
                            checkNumVO.setInsMfNum(highGradeNum);
                        }
                    }
                }
                // 去找下一个年级
                subNum = subNum - highGradeNum;
                grade -= 1;
                String gradeCode = GradeEnum.getEnCodeByCode(grade);
                // 最高年级的附加险数量
                highGradeNum = zxMap.get(gradeCode);
                if (highGradeNum == null) {
                    highGradeNum = 0;
                }
                if (grade > 0) {
                    return calculateFjBbxrNum(resultList, subNum, grade, highGradeNum, zxMap);
                }
                if (subNum > 0) {
                    // todo
                    // 说明 扣完附加被保险人的人数后 ，优惠名额还有剩余，需要继续递归循环，去循环 只买主险的人数，也是从高年级向低年级依次扣
                    // 首先组装一个  年级  主险 人数的map
                    Map<String, Integer> szZxMap = new HashMap<>();
                    for (CheckNumVO checkNumVO : resultList) {
                        String nj = checkNumVO.getGrade();
                        Integer insNum4 = checkNumVO.getInsNum4();
                        szZxMap.put(nj, insNum4);
                    }
                    grade = 7;
                    gradeCode = GradeEnum.getEnCodeByCode(grade);
                    // 最高年级的只买 主险 的人数
                    highGradeNum = szZxMap.get(gradeCode);
                    if (highGradeNum == null) {
                        highGradeNum = 0;
                    }
                    return calculateSZZXNum(resultList, subNum, grade, highGradeNum, szZxMap);
                }

            } else {
                // 直接在本年级扣了
                for (CheckNumVO checkNumVO : resultList) {
                    String grade1 = checkNumVO.getGrade();
                    String currentGrade = GradeEnum.getEnCodeByCode(grade);

                    // 根据one 得到 1  当前年级
                    byte codeByenCode = GradeEnum.getCodeByenCode(grade1);

                    if (StringUtils.equals(currentGrade, grade1)) {// 本年级 附加被保险人 有免费，也有付费；实习无过失险人数全部免费，  双附加险 全部免费  其他 全部付费
                        checkNumVO.setSxAInsMfNum(checkNumVO.getInsNum3());
                        checkNumVO.setSxAInsFfNum(0);
                        // 附加被保险人
                        checkNumVO.setInsMfNum(subNum + checkNumVO.getInsNum3());
                        checkNumVO.setInsFfNum(checkNumVO.getInsNum2() - subNum);
                        // 实习无过失
                        checkNumVO.setInsSxMfNum(checkNumVO.getInsNum1() + checkNumVO.getInsNum3());
                        checkNumVO.setInsSxFfNum(0);

                        if ((checkNumVO.getInsNum1() + checkNumVO.getInsNum3()) > (subNum + checkNumVO.getInsNum3())) {
                            checkNumVO.setInsNum5(subNum + checkNumVO.getInsNum3() + checkNumVO.getInsNum1());
                            checkNumVO.setInsNum6(checkNumVO.getGradeNum() - subNum + checkNumVO.getInsNum3() - checkNumVO.getInsNum1());
                        } else {
                            checkNumVO.setInsNum5(subNum + checkNumVO.getInsNum3());
                            checkNumVO.setInsNum6(checkNumVO.getGradeNum() - checkNumVO.getInsNum3() - subNum);
                        }
                    } else if (codeByenCode > grade) {// 当前年级的高年级：双附加险 全部免费，实习无过失险人数，全部免费；附加被保险人 全部免费, 其他付费
                        checkNumVO.setSxAInsMfNum(checkNumVO.getInsNum3());
                        checkNumVO.setSxAInsFfNum(0);
                        // 实习无过失
                        checkNumVO.setInsSxMfNum(checkNumVO.getInsNum1() + checkNumVO.getInsNum3());
                        checkNumVO.setInsSxFfNum(0);
                        // 附加被保险人
                        checkNumVO.setInsMfNum(checkNumVO.getInsNum2() + checkNumVO.getInsNum3());
                        checkNumVO.setInsFfNum(0);
                        if ((checkNumVO.getInsNum1() + checkNumVO.getInsNum3()) > (checkNumVO.getInsNum2() + checkNumVO.getInsNum3())) {
                            checkNumVO.setInsNum5(checkNumVO.getInsNum1() + checkNumVO.getInsNum3());
                            checkNumVO.setInsNum6(checkNumVO.getGradeNum() - checkNumVO.getInsNum3() - checkNumVO.getInsNum1());
                        } else {
                            checkNumVO.setInsNum5(checkNumVO.getInsNum2() + checkNumVO.getInsNum3());
                            checkNumVO.setInsNum6(checkNumVO.getGradeNum() - checkNumVO.getInsNum3() - checkNumVO.getInsNum2());
                        }
                    } else if (codeByenCode < grade) {// 当前年级的低年级：双附加险 全部免费，实习无过失险人数，全部免费， 其他付费
                        checkNumVO.setSxAInsMfNum(checkNumVO.getInsNum3());
                        checkNumVO.setSxAInsFfNum(0);
                        // 实习无过失
                        checkNumVO.setInsSxMfNum(checkNumVO.getInsNum1() + checkNumVO.getInsNum3());
                        checkNumVO.setInsSxFfNum(0);
                        // 附加被保险人
                        checkNumVO.setInsMfNum(checkNumVO.getInsNum3());
                        checkNumVO.setInsFfNum(checkNumVO.getInsNum2());


                        checkNumVO.setInsNum5(checkNumVO.getInsNum3() + checkNumVO.getInsNum1());
                        checkNumVO.setInsNum6(checkNumVO.getGradeNum() - checkNumVO.getInsNum3() - checkNumVO.getInsNum1());
                    }

                }
            }

        } else {
            // 去找下一个年级
            grade -= 1;
            String gradeCode = GradeEnum.getEnCodeByCode(grade);
            // 最高年级的附加险数量
            highGradeNum = zxMap.get(gradeCode);
            if (highGradeNum == null) {
                highGradeNum = 0;
            }
            if (grade > 0) {
                return calculateFjBbxrNum(resultList, subNum, grade, highGradeNum, zxMap);
            }
        }

        return resultList;
    }

    private List<CheckNumVO> calculateSZZXNum(List<CheckNumVO> resultList, int subNum, byte grade, Integer highGradeNum, Map<String, Integer> zxMap) {

        if (highGradeNum != null && highGradeNum > 0) {
            // 优惠名额 - 主险人 人数
            int i = subNum - highGradeNum;
            if (i > 0) {
                for (CheckNumVO checkNumVO : resultList) {
                    if (StringUtils.equals(GradeEnum.getEnCodeByCode(grade), checkNumVO.getGrade())) {
                        if (checkNumVO.getInsNum5() != null && checkNumVO.getInsNum5().compareTo(0) > 0) {
                            checkNumVO.setInsNum5(checkNumVO.getInsNum5() + highGradeNum);
                        } else {
                            checkNumVO.setInsNum5(highGradeNum);
                        }
                    }
                }
                // 去找下一个年级
                subNum = subNum - highGradeNum;
                grade -= 1;
                String gradeCode = GradeEnum.getEnCodeByCode(grade);
                // 最高年级的主险数量
                highGradeNum = zxMap.get(gradeCode);
                if (highGradeNum == null) {
                    highGradeNum = 0;
                }
                if (grade > 0) {
                    calculateSZZXNum(resultList, subNum, grade, highGradeNum, zxMap);
                }
                if (grade < 1) {
                    return resultList;
                }
            } else {
                // 直接在本年级扣了
                for (CheckNumVO checkNumVO : resultList) {
                    String grade1 = checkNumVO.getGrade();
                    String currentGrade = GradeEnum.getEnCodeByCode(grade);

                    // 根据one 得到 1  当前年级
                    byte codeByenCode = GradeEnum.getCodeByenCode(grade1);

                    if (StringUtils.equals(currentGrade, grade1)) {// 本年级主险 有免费，有付费；  其他全部免费
                        checkNumVO.setSxAInsMfNum(checkNumVO.getInsNum3());
                        checkNumVO.setSxAInsFfNum(0);
                        // 附加被保险人
                        checkNumVO.setInsMfNum(checkNumVO.getInsNum2() + checkNumVO.getInsNum3());
                        checkNumVO.setInsFfNum(0);
                        // 实习无过失
                        checkNumVO.setInsSxMfNum(checkNumVO.getInsNum1() + checkNumVO.getInsNum3());
                        checkNumVO.setInsSxFfNum(0);

                        if ((checkNumVO.getInsNum2() + checkNumVO.getInsNum3()) > (checkNumVO.getInsNum1() + checkNumVO.getInsNum3())) {
                            checkNumVO.setInsNum5(subNum + checkNumVO.getInsNum2() + checkNumVO.getInsNum3());
                            checkNumVO.setInsNum6(checkNumVO.getGradeNum() - checkNumVO.getInsNum3() - checkNumVO.getInsNum2() - subNum);
                        } else {
                            checkNumVO.setInsNum5(subNum + checkNumVO.getInsNum1() + checkNumVO.getInsNum3());
                            checkNumVO.setInsNum6(checkNumVO.getGradeNum() - checkNumVO.getInsNum3() - subNum - checkNumVO.getInsNum1());
                        }


                    } else if (codeByenCode > grade) {// 当前年级的高年级：全部免费
                        checkNumVO.setSxAInsMfNum(checkNumVO.getInsNum3());
                        checkNumVO.setSxAInsFfNum(0);
                        // 附加被保险人
                        checkNumVO.setInsMfNum(checkNumVO.getInsNum2() + checkNumVO.getInsNum3());
                        checkNumVO.setInsFfNum(0);
                        // 实习无过失
                        checkNumVO.setInsSxMfNum(checkNumVO.getInsNum1() + checkNumVO.getInsNum3());
                        checkNumVO.setInsSxFfNum(0);

                        checkNumVO.setInsNum5(checkNumVO.getGradeNum());
                        checkNumVO.setInsNum6(0);
                    } else if (codeByenCode < grade) {// 当前年级的低年级：主险全部付费，其他全部免费
                        checkNumVO.setSxAInsMfNum(checkNumVO.getInsNum3());
                        checkNumVO.setSxAInsFfNum(0);
                        // 附加被保险人
                        checkNumVO.setInsMfNum(checkNumVO.getInsNum2() + checkNumVO.getInsNum3());
                        checkNumVO.setInsFfNum(0);
                        // 实习无过失
                        checkNumVO.setInsSxMfNum(checkNumVO.getInsNum1() + checkNumVO.getInsNum3());
                        checkNumVO.setInsSxFfNum(0);

                        if ((checkNumVO.getInsNum2() + checkNumVO.getInsNum3()) > (checkNumVO.getInsNum1() + checkNumVO.getInsNum3())) {
                            checkNumVO.setInsNum5(checkNumVO.getInsNum2() + checkNumVO.getInsNum3());
                            checkNumVO.setInsNum6(checkNumVO.getGradeNum() - checkNumVO.getInsNum2() - checkNumVO.getInsNum3());
                        } else {
                            checkNumVO.setInsNum5(checkNumVO.getInsNum1() + checkNumVO.getInsNum3());
                            checkNumVO.setInsNum6(checkNumVO.getGradeNum() - checkNumVO.getInsNum1() - checkNumVO.getInsNum3());
                        }
                    }
                }
            }

        } else {
            // 去找下一个年级
            grade -= 1;
            String gradeCode = GradeEnum.getEnCodeByCode(grade);
            // 最高年级的主险人数
            highGradeNum = zxMap.get(gradeCode);
            if (highGradeNum == null) {
                highGradeNum = 0;
            }
            if (grade > 0) {
                return calculateSZZXNum(resultList, subNum, grade, highGradeNum, zxMap);
            }

        }

        return resultList;
    }


    private List<CheckNumVO> calculateSubZxNum(List<CheckNumVO> resultList, int subNum, byte grade, Integer highGradeNum, Map<String, Integer> map) {

        // todo 获取到传参中的数据 先扣除只买主险的，从低年级先扣

        if (highGradeNum != null && highGradeNum > 0) {
            // 优惠名额 - 低年级主险人数
            int i = subNum - highGradeNum;
            if (i > 0) {

                // 去找下一年级
                subNum = subNum - highGradeNum;
                grade += 1;
                String gradeCode = GradeEnum.getEnCodeByCode(grade);
                // 最低年级的主险数量
                highGradeNum = map.get(gradeCode);
                if (highGradeNum == null) {
                    highGradeNum = 0;
                }
                if (grade > 7 && subNum > 0) {
                    // 说明 扣完主险 的人数后 ，优惠名额还有剩余，需要继续递归循环,循环附加被保险人的
                    // 首先组装一个 年级  附加险人数的map
                    Map<String, Integer> fjSubMap = new HashMap<>();
                    for (CheckNumVO checkNumVO : resultList) {
                        String nj = checkNumVO.getGrade();
                        Integer insNum2 = checkNumVO.getInsNum2();
                        fjSubMap.put(nj, insNum2);
                    }
                    grade = 1;
                    gradeCode = GradeEnum.getEnCodeByCode(grade);
                    // 最低年级的只买附加被保险人的人数
                    highGradeNum = fjSubMap.get(gradeCode);
                    if (highGradeNum == null) {
                        highGradeNum = 0;
                    }
                    return calculateFjBbxrSubxNum(resultList, subNum, grade, highGradeNum, fjSubMap);
                }
                if (grade < 8) {
                    return calculateSubZxNum(resultList, subNum, grade, highGradeNum, map);
                }
            } else {
                // 直接在本年级扣了
                for (CheckNumVO checkNumVO : resultList) {
                    String grade1 = checkNumVO.getGrade();
                    String currentGrade = GradeEnum.getEnCodeByCode(grade);

                    // 当前年级
                    byte codeByenCode = GradeEnum.getCodeByenCode(grade1);

                    if (StringUtils.equals(currentGrade, grade1)) {// 本年级主险 有免费，有付费；其他全部付费

                        checkNumVO.setSxAInsMfNum(0);
                        checkNumVO.setSxAInsFfNum(checkNumVO.getInsNum3());
                        // 附加被保险人
                        checkNumVO.setInsMfNum(0);
                        checkNumVO.setInsFfNum(checkNumVO.getInsNum2() + checkNumVO.getInsNum3());
                        // 实习无过失
                        checkNumVO.setInsSxMfNum(0);
                        checkNumVO.setInsSxFfNum(checkNumVO.getInsNum1() + checkNumVO.getInsNum3());

                        checkNumVO.setInsNum5(subNum);
                        checkNumVO.setInsNum6(checkNumVO.getGradeNum() - subNum);
                    } else if (codeByenCode > grade) {// 当前年级的高年级：没扣到  全部付费
                        checkNumVO.setSxAInsMfNum(0);
                        checkNumVO.setSxAInsFfNum(checkNumVO.getInsNum3());
                        // 实习无过失
                        checkNumVO.setInsSxMfNum(0);
                        checkNumVO.setInsSxFfNum(checkNumVO.getInsNum1() + checkNumVO.getInsNum3());
                        // 附加被保险人
                        checkNumVO.setInsMfNum(0);
                        checkNumVO.setInsFfNum(checkNumVO.getInsNum2() + checkNumVO.getInsNum3());
                        checkNumVO.setInsNum5(0);
                        checkNumVO.setInsNum6(checkNumVO.getGradeNum());
                    } else if (codeByenCode < grade) {// 当前年级的低年级：只买主险全部免费，其他险种全部付费
                        checkNumVO.setSxAInsMfNum(0);
                        checkNumVO.setSxAInsFfNum(checkNumVO.getInsNum3());
                        // 附加被保险人
                        checkNumVO.setInsMfNum(0);
                        checkNumVO.setInsFfNum(checkNumVO.getInsNum2() + checkNumVO.getInsNum3());
                        // 实习无过失
                        checkNumVO.setInsSxMfNum(0);
                        checkNumVO.setInsSxFfNum(checkNumVO.getInsNum1() + checkNumVO.getInsNum3());


                        checkNumVO.setInsNum5(checkNumVO.getInsNum4());
                        checkNumVO.setInsNum6(checkNumVO.getGradeNum() - checkNumVO.getInsNum4());
                    }


                }
            }

        } else {
            // 去找下一年级
            grade += 1;
            String gradeCode = GradeEnum.getEnCodeByCode(grade);
            // 最高年级的附加险数量
            highGradeNum = map.get(gradeCode);
            if (highGradeNum == null) {
                highGradeNum = 0;
            }
            if (grade < 8) {
                calculateSubZxNum(resultList, subNum, grade, highGradeNum, map);
            }
        }


        return resultList;
    }


    private List<CheckNumVO> calculateFjBbxrSubxNum(List<CheckNumVO> resultList, int subNum, byte grade, Integer highGradeNum, Map<String, Integer> fjSubMap) {
        // todo
        if (highGradeNum != null && highGradeNum > 0) {
            // 优惠名额 - 低年级附加险人数
            int i = subNum - highGradeNum;
            if (i > 0) {
                // 去找下一个年级
                subNum = subNum - highGradeNum;
                grade += 1;
                String gradeCode = GradeEnum.getEnCodeByCode(grade);
                // 最低年级的附加险数量
                highGradeNum = fjSubMap.get(gradeCode);
                if (highGradeNum == null) {
                    highGradeNum = 0;
                }
                if (grade > 7 && subNum > 0) {
                    // 说明 扣完被保险人附加险 的人数后 ，优惠名额还有剩余，需要继续递归循环,循环实习无过失的
                    // 首先组装一个 年级  实习无过失 人数 的map
                    Map<String, Integer> sxWgsSubMap = new HashMap<>();
                    for (CheckNumVO checkNumVO : resultList) {
                        String nj = checkNumVO.getGrade();
                        Integer insNum1 = checkNumVO.getInsNum1();
                        sxWgsSubMap.put(nj, insNum1);
                    }
                    grade = 1;
                    gradeCode = GradeEnum.getEnCodeByCode(grade);
                    // 最低年级的只买实习无过失 保险人的人数
                    highGradeNum = sxWgsSubMap.get(gradeCode);
                    if (highGradeNum == null) {
                        highGradeNum = 0;
                    }
                    return calculateSxWgsSubxNum(resultList, subNum, grade, highGradeNum, sxWgsSubMap);
                }
                if (grade < 8) {
                    calculateFjBbxrSubxNum(resultList, subNum, grade, highGradeNum, fjSubMap);
                }


            } else {
                // 直接在本年级扣了  todo
                for (CheckNumVO checkNumVO : resultList) {
                    String grade1 = checkNumVO.getGrade();
                    String currentGrade = GradeEnum.getEnCodeByCode(grade);

                    // 根据one 得到 1
                    byte codeByenCode = GradeEnum.getCodeByenCode(grade1);

                    if (StringUtils.equals(currentGrade, grade1)) {// 本年级 附加被保险人 有免费  有付费，主险 全部免费， 其他全部付费
                        checkNumVO.setSxAInsMfNum(0);
                        checkNumVO.setSxAInsFfNum(checkNumVO.getInsNum3());
                        // 附加被保险人
                        checkNumVO.setInsMfNum(subNum);
                        checkNumVO.setInsFfNum(checkNumVO.getInsNum2() - subNum + checkNumVO.getInsNum3());
                        // 实习无过失
                        checkNumVO.setInsSxMfNum(0);
                        checkNumVO.setInsSxFfNum(checkNumVO.getInsNum1() + checkNumVO.getInsNum3());

                        checkNumVO.setInsNum5(checkNumVO.getInsNum4() + subNum);
                        checkNumVO.setInsNum6(checkNumVO.getGradeNum() - (checkNumVO.getInsNum4() + subNum));

                    } else if (codeByenCode < grade) {// 当前年级的低年级  全部扣减完毕,附加被保险人免费，主险免费，其他全部付费
                        checkNumVO.setSxAInsMfNum(0);
                        checkNumVO.setSxAInsFfNum(checkNumVO.getInsNum3());
                        // 附加被保险人
                        checkNumVO.setInsMfNum(checkNumVO.getInsNum2());
                        checkNumVO.setInsFfNum(checkNumVO.getInsNum3());
                        // 实习无过失
                        checkNumVO.setInsSxMfNum(0);
                        checkNumVO.setInsSxFfNum(checkNumVO.getInsNum1() + checkNumVO.getInsNum3());

                        checkNumVO.setInsNum5(checkNumVO.getInsNum4() + checkNumVO.getInsNum2());
                        checkNumVO.setInsNum6(checkNumVO.getGradeNum() - (checkNumVO.getInsNum4() + checkNumVO.getInsNum2()));
                    } else if (codeByenCode > grade) {// 当前年级  高年级 ，未扣减，主险全部免费，被保险人 付费，其他付费
                        checkNumVO.setSxAInsMfNum(0);
                        checkNumVO.setSxAInsFfNum(checkNumVO.getInsNum3());
                        // 附加被保险人
                        checkNumVO.setInsMfNum(0);
                        checkNumVO.setInsFfNum(checkNumVO.getInsNum2() + checkNumVO.getInsNum3());
                        // 实习无过失
                        checkNumVO.setInsSxMfNum(0);
                        checkNumVO.setInsSxFfNum(checkNumVO.getInsNum1() + checkNumVO.getInsNum3());

                        checkNumVO.setInsNum5(checkNumVO.getInsNum4());
                        checkNumVO.setInsNum6(checkNumVO.getGradeNum() - checkNumVO.getInsNum4());
                    }

                }
            }

        } else {
            // 去找下一个年级
            grade += 1;
            String gradeCode = GradeEnum.getEnCodeByCode(grade);
            // 最低年级的被保险人数量
            highGradeNum = fjSubMap.get(gradeCode);
            if (highGradeNum == null) {
                highGradeNum = 0;
            }
            if (grade < 8) {
                return calculateFjBbxrSubxNum(resultList, subNum, grade, highGradeNum, fjSubMap);
            }
        }

        return resultList;
    }


    private List<CheckNumVO> calculateSxWgsSubxNum(List<CheckNumVO> resultList, int subNum, byte grade, Integer highGradeNum, Map<String, Integer> fjSubMap) {
        // todo
        if (highGradeNum != null && highGradeNum > 0) {
            // 优惠名额 - 低年级实习无过失 人数
            int i = subNum - highGradeNum;
            if (i > 0) {
                // 去找下一个年级
                subNum = subNum - highGradeNum;
                grade += 1;
                String gradeCode = GradeEnum.getEnCodeByCode(grade);
                // 最低年级的实习无过失 数量
                highGradeNum = fjSubMap.get(gradeCode);
                if (highGradeNum == null) {
                    highGradeNum = 0;
                }
                if (grade > 7 && subNum > 0) {

                    // todo  腾飞
                    // 说明 扣完实习无过失 附加险 的人数后 ，优惠名额还有剩余，需要继续递归循环,循环双保险的
                    // 首先组装一个 年级  双保险 人数 的map
                    Map<String, Integer> sbxSubMap = new HashMap<>();
                    for (CheckNumVO checkNumVO : resultList) {
                        String nj = checkNumVO.getGrade();
                        Integer insNum2 = checkNumVO.getInsNum2();
                        sbxSubMap.put(nj, insNum2);
                    }
                    grade = 1;
                    gradeCode = GradeEnum.getEnCodeByCode(grade);
                    // 最低年级的只买实习无过失 保险人的人数
                    highGradeNum = sbxSubMap.get(gradeCode);
                    if (highGradeNum == null) {
                        highGradeNum = 0;
                    }
                    return calculateSBXSubxNum(resultList, subNum, grade, highGradeNum, sbxSubMap);
                }
                if (grade < 8) {
                    calculateSxWgsSubxNum(resultList, subNum, grade, highGradeNum, fjSubMap);
                }
            } else {
                // 直接在本年级扣了  todo
                for (CheckNumVO checkNumVO : resultList) {
                    String grade1 = checkNumVO.getGrade();
                    String currentGrade = GradeEnum.getEnCodeByCode(grade);

                    // 根据one 得到 1
                    byte codeByenCode = GradeEnum.getCodeByenCode(grade1);

                    if (StringUtils.equals(currentGrade, grade1)) {// 本年级 实习无过失 有免费  有付费，双主险 全部付费，主险 全部免费，附加被保险人免费

                        checkNumVO.setSxAInsMfNum(0);
                        checkNumVO.setSxAInsFfNum(checkNumVO.getInsNum3());
                        // 附加被保险人
                        checkNumVO.setInsMfNum(checkNumVO.getInsNum2());
                        checkNumVO.setInsFfNum(checkNumVO.getInsNum3());
                        // 实习无过失
                        checkNumVO.setInsSxMfNum(subNum);
                        checkNumVO.setInsSxFfNum(checkNumVO.getInsNum1() - subNum + checkNumVO.getInsNum3());

                        if ((checkNumVO.getInsNum2()) > (subNum)) {
                            checkNumVO.setInsNum5(checkNumVO.getInsNum4() + checkNumVO.getInsNum2());
                            checkNumVO.setInsNum6(checkNumVO.getGradeNum() - checkNumVO.getInsNum4() - checkNumVO.getInsNum2());
                        } else {
                            checkNumVO.setInsNum5(checkNumVO.getInsNum4() + subNum);
                            checkNumVO.setInsNum6(checkNumVO.getGradeNum() - (checkNumVO.getInsNum4() + subNum));
                        }

                    } else if (codeByenCode < grade) {// 当前年级的低年级  全部扣减完毕,双主险 全部付费，其他全部免费  todo
                        checkNumVO.setSxAInsMfNum(0);
                        checkNumVO.setSxAInsFfNum(checkNumVO.getInsNum3());
                        // 附加被保险人
                        checkNumVO.setInsMfNum(checkNumVO.getInsNum2());
                        checkNumVO.setInsFfNum(checkNumVO.getInsNum3());
                        // 实习无过失
                        checkNumVO.setInsSxMfNum(checkNumVO.getInsNum1());
                        checkNumVO.setInsSxFfNum(checkNumVO.getInsNum3());

                        if ((checkNumVO.getInsNum2()) > (checkNumVO.getInsNum1())) {
                            checkNumVO.setInsNum5(checkNumVO.getInsNum4() + checkNumVO.getInsNum2());
                            checkNumVO.setInsNum6(checkNumVO.getGradeNum() - (checkNumVO.getInsNum4() + checkNumVO.getInsNum2()));
                        } else {
                            checkNumVO.setInsNum5(checkNumVO.getInsNum4() + checkNumVO.getInsNum1());
                            checkNumVO.setInsNum6(checkNumVO.getGradeNum() - (checkNumVO.getInsNum4() + checkNumVO.getInsNum1()));
                        }

                    } else if (codeByenCode > grade) {// 当前年级  高年级 ，未扣减，实习无过失 付费，双主险付费，其他免费  todo
                        checkNumVO.setSxAInsMfNum(0);
                        checkNumVO.setSxAInsFfNum(checkNumVO.getInsNum3());
                        // 附加被保险人
                        checkNumVO.setInsMfNum(checkNumVO.getInsNum2());
                        checkNumVO.setInsFfNum(checkNumVO.getInsNum3());
                        // 实习无过失
                        checkNumVO.setInsSxMfNum(0);
                        checkNumVO.setInsSxFfNum(checkNumVO.getInsNum1() + checkNumVO.getInsNum3());

                        checkNumVO.setInsNum5(checkNumVO.getInsNum4() + checkNumVO.getInsNum2());
                        checkNumVO.setInsNum6(checkNumVO.getGradeNum() - (checkNumVO.getInsNum4() + checkNumVO.getInsNum2()));
                    }

                }
            }

        } else {
            // 去找下一个年级
            grade += 1;
            String gradeCode = GradeEnum.getEnCodeByCode(grade);
            // 最低年级的被保险人数量
            highGradeNum = fjSubMap.get(gradeCode);
            if (highGradeNum == null) {
                highGradeNum = 0;
            }
            if (grade < 8) {
                return calculateSxWgsSubxNum(resultList, subNum, grade, highGradeNum, fjSubMap);
            }
        }
        return resultList;
    }


    private List<CheckNumVO> calculateSBXSubxNum(List<CheckNumVO> resultList, int subNum, byte grade, Integer highGradeNum, Map<String, Integer> fjSubMap) {
        // todo
        if (highGradeNum != null && highGradeNum > 0) {
            // 优惠名额 - 双保险 人数
            int i = subNum - highGradeNum;
            if (i > 0) {
                // 去找下一个年级
                subNum = subNum - highGradeNum;
                grade += 1;
                String gradeCode = GradeEnum.getEnCodeByCode(grade);
                // 最低年级的实习无过失 数量
                highGradeNum = fjSubMap.get(gradeCode);
                if (highGradeNum == null) {
                    highGradeNum = 0;
                }
                if (grade < 8) {
                    calculateSBXSubxNum(resultList, subNum, grade, highGradeNum, fjSubMap);
                } else {
                    return resultList;
                }
            } else {
                // 直接在本年级扣了
                for (CheckNumVO checkNumVO : resultList) {
                    String grade1 = checkNumVO.getGrade();
                    String currentGrade = GradeEnum.getEnCodeByCode(grade);

                    // 根据one 得到 1
                    byte codeByenCode = GradeEnum.getCodeByenCode(grade1);

                    if (StringUtils.equals(currentGrade, grade1)) {// 本年级 双保险有免费，有付费，其他全部免费

                        checkNumVO.setSxAInsMfNum(subNum);
                        checkNumVO.setSxAInsFfNum(checkNumVO.getInsNum3() - subNum);

                        // 附加被保险人
                        checkNumVO.setInsMfNum(checkNumVO.getInsNum2() + subNum);
                        checkNumVO.setInsFfNum(checkNumVO.getInsNum3() - subNum);
                        // 实习无过失
                        checkNumVO.setInsSxMfNum(checkNumVO.getInsNum1() + subNum);
                        checkNumVO.setInsSxFfNum(checkNumVO.getInsNum3() - subNum);

                        if ((checkNumVO.getInsNum2() + subNum) > (checkNumVO.getInsNum1() + subNum)) {
                            checkNumVO.setInsNum5(checkNumVO.getInsNum4() + checkNumVO.getInsNum2() + subNum);
                            checkNumVO.setInsNum6(checkNumVO.getGradeNum() - (checkNumVO.getInsNum4() + checkNumVO.getInsNum2() + subNum));
                        } else {
                            checkNumVO.setInsNum5(checkNumVO.getInsNum4() + checkNumVO.getInsNum1() + subNum);
                            checkNumVO.setInsNum6(checkNumVO.getGradeNum() - (checkNumVO.getInsNum4() + checkNumVO.getInsNum1() + subNum));
                        }

                    } else if (codeByenCode < grade) {// 当前年级的低年级  全部扣减完毕,双主险 全部免费，其他全部免费
                        checkNumVO.setSxAInsMfNum(checkNumVO.getInsNum3());
                        checkNumVO.setSxAInsFfNum(0);
                        // 附加被保险人
                        checkNumVO.setInsMfNum(checkNumVO.getInsNum2() + checkNumVO.getInsNum3());
                        checkNumVO.setInsFfNum(0);
                        // 实习无过失
                        checkNumVO.setInsSxMfNum(checkNumVO.getInsNum1() + checkNumVO.getInsNum3());
                        checkNumVO.setInsSxFfNum(0);

                        checkNumVO.setInsNum5(checkNumVO.getGradeNum());
                        checkNumVO.setInsNum6(0);
                    } else if (codeByenCode > grade) {// 当前年级  高年级 ，未扣减，双主险付费，其他免费
                        checkNumVO.setSxAInsMfNum(0);
                        checkNumVO.setSxAInsFfNum(checkNumVO.getInsNum3());
                        // 附加被保险人
                        checkNumVO.setInsMfNum(checkNumVO.getInsNum2());
                        checkNumVO.setInsFfNum(checkNumVO.getInsNum3());
                        // 实习无过失
                        checkNumVO.setInsSxMfNum(checkNumVO.getInsNum1());
                        checkNumVO.setInsSxFfNum(checkNumVO.getInsNum3());

                        if ((checkNumVO.getInsNum2()) > (checkNumVO.getInsNum1())) {
                            checkNumVO.setInsNum5(checkNumVO.getInsNum4() + checkNumVO.getInsNum2());
                            checkNumVO.setInsNum6(checkNumVO.getGradeNum() - (checkNumVO.getInsNum4() + checkNumVO.getInsNum2()));
                        } else {
                            checkNumVO.setInsNum5(checkNumVO.getInsNum4() + checkNumVO.getInsNum1());
                            checkNumVO.setInsNum6(checkNumVO.getGradeNum() - (checkNumVO.getInsNum4() + checkNumVO.getInsNum1()));
                        }
                    }
                }
            }

        } else {
            // 去找下一个年级
            grade += 1;
            String gradeCode = GradeEnum.getEnCodeByCode(grade);
            // 最低年级的被保险人数量
            highGradeNum = fjSubMap.get(gradeCode);
            if (highGradeNum == null) {
                highGradeNum = 0;
            }
            if (grade < 8) {
                calculateSBXSubxNum(resultList, subNum, grade, highGradeNum, fjSubMap);
            } else {
                return resultList;
            }

        }
        return resultList;
    }

}
